package com.azhoucode.util;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.serializer.SerializeConfig;
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.alibaba.fastjson.serializer.SimpleDateFormatSerializer;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.StringUtils;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;

public class JsonUtils {

    private final static Logger logger = LoggerFactory.getLogger(JsonUtils.class);

    private static final SerializeConfig config;

    private static final String EMPTY_STRING = "";

    static {
        config = new SerializeConfig();
        config.put(Date.class, new SimpleDateFormatSerializer("yyyy-MM-dd HH:mm:ss"));
    }

    private static final SerializerFeature[] serializerFeatures = {
            // 输出空置字段
            SerializerFeature.WriteMapNullValue,
            // list字段如果为null，输出为[]，而不是null
            SerializerFeature.WriteNullListAsEmpty,
            // 数值字段如果为null，输出为0，而不是null
//            SerializerFeature.WriteNullNumberAsZero,
            // Boolean字段如果为null，输出为false，而不是null
//            SerializerFeature.WriteNullBooleanAsFalse,
            // 字符类型字段如果为null，输出为""，而不是null
//            SerializerFeature.WriteNullStringAsEmpty
    };

    private JsonUtils() {}

    /**
     * Object转json字符串输出
     * @param object    bean
     * @return          {@link String}
     */
    public static String objectToJson(Object object) {
        if (object == null) {
            return EMPTY_STRING;
        }
        try {
            return JSON.toJSONString(object, config, serializerFeatures);
        } catch (Exception e) {
            logger.error("JsonUtil | method=objectToJson() | 对象转为Json字符串 Error！", e);
            return EMPTY_STRING;
        }
    }


    /**
     * 转换为Object数组
     * @param json  json字符串
     * @return      {@link java.util.Arrays}
     */
    public static Object[] toArray(String json) {
        if (StringUtils.isEmpty(json)) {
            return new Object[0];
        }
        try {
            return toArray(json, null);
        } catch (Exception e) {
            logger.error("JsonUtil | method=toArray() | 将json格式的数据转换为数组 Object  Error！", e);
            return new Object[0];
        }
    }

    /**
     * 转换为自定泛型的数组
     * @param json     json串
     * @param clazz     {@link Class}
     * @param <T>       数组泛型
     * @return          object数组
     */
    public static <T> Object[] toArray(String json, Class<T> clazz) {
        if (StringUtils.isEmpty(json)) {
            return new Object[0];
        }
        try {
            return JSON.parseArray(json, clazz).toArray();
        } catch (Exception e) {
            logger.error("JsonUtil | method=toArray() | 将json格式的数据转换为数组 （可指定类型）   Error！" + e.getMessage(), e);
            return new Object[0];
        }
    }

    /**
     * json转为java bean
     * @param json      json串
     * @param clazz     {@link Class}
     * @param <T>       bean泛型
     * @return          T
     */
    public static <T> T jsonToObject(String json, Class<T> clazz) {
        if (StringUtils.isEmpty(json)) {
            return null;
        }
        try {
            return JSON.parseObject(json, clazz);
        } catch (Exception e) {
            logger.error("JsonUtil | method=jsonToObject() | Json 转为  Java Bean  Error！" + e.getMessage(), e);
            return null;
        }
    }


    public static Map<String, Object> jsonToMap(String json) {
        if (StringUtils.isEmpty(json)) {
            return null;
        }
        try {
            return JSON.parseObject(json);
        } catch (Exception e) {
            logger.error("JsonUtil | method=jsonToMap() | Json 转为 Map {},{}" + e.getMessage(), e);
        }
        return null;
    }

    public static <T> T jsonToMap(String json, Class<T> clazz) {
        if (StringUtils.isEmpty(json)) {
            return null;
        }
        try {
            return JSON.parseObject(json, clazz);
        } catch (Exception e) {
            logger.error("JsonUtil | method=jsonToMap() | Json 转为 Map {},{}" + e.getMessage(), e);
            return null;
        }
    }

    /**
     * json 转 List
     * @param json      json串
     * @param clazz     {@link Class}
     * @param <T>       集合泛型
     * @return          {@link List}
     */
    public static <T> List<T> toList(String json, Class<T> clazz) {
        if (StringUtils.isEmpty(json)) {
            return new ArrayList<>();
        }
        try {
            return JSON.parseArray(json, clazz);
        } catch (Exception e) {
            logger.error("JsonUtil | method=toList() | Json 转为List发生异常。", e);
            return new ArrayList<>();
        }
    }

    /**
     * 从json字符串获取指定key的字符串
     * @param json  json串
     * @param key   key
     * @return      key对应的值
     */
    public static String getStringFromJson(final String json, final String key) {
        if (StringUtils.isEmpty(json)) {
            return EMPTY_STRING;
        }
        try {
            if (StringUtils.isEmpty(json) || StringUtils.isEmpty(key)) {
                return EMPTY_STRING;
            }
            return JSON.parseObject(json).getString(key);
        } catch (Exception e) {
            logger.error("JsonUtil | method=getStringFromJson() | 从json获取指定key的字符串 Error！" + e.getMessage(), e);
            return EMPTY_STRING;
        }
    }

    /**
     * 从json字符串获取指定key的字符串，并转换为指定的类型
     * @param json      json串
     * @param key       指定key
     * @param clazz     key值
     * @param <T>       值得泛型
     * @return          T
     */
    public static <T> T getValueFromJson(final String json, final String key, Class<T> clazz) {
        if (StringUtils.isEmpty(json)) {
            return null;
        }
        try {
            if (StringUtils.isEmpty(json) || StringUtils.isEmpty(key)) {
                return null;
            }
            return JSON.parseObject(json).getObject(key, clazz);
        } catch (Exception e) {
            logger.error("JsonUtil | method=getValueFromJson() | 从json获取指定key的字符串 Error！" + e.getMessage(), e);
        }
        return null;
    }
}
